计算 Lua 的 Table长度

在 Lua 中,我们可以通过这个符号”#“ 来计算字符串的长度和一个table的长度,比如:

str = "I'am a string!"
print(#str) => 14

通常这个#符号也可以用来计算一个 Table 的长度,比如:

t = {1, 2, 3, 5, 100}
print(#t) => 5

t = {1, 2, 3, 5, {}, 100}
print(#t) => 6

上面两个例子都很好理解,再来看一个:

t = {1, 2, a=3, 5, {}, 100}
print(#t) => 5

这里 a=3 不能算是sequence序列的一个成员,所以a=3并没有被统计进去,再来看看这个列子:

t = {1, 2, a=3, nil, 100}
print(#t)

这个大家可以试试,我的lua版本是5.2 输出结果是 4

t = {1, 2, a=3, nil}
print(#t) => 2

可以看到,当sequence中有nil的时候,这个结果就有点不好理解了,如果nil也被统计进长度,那么上面的例子输出应该是3而不是2,如果不统计那么倒数第二个例子应该是输出3而不是4,这是为什么呢?

先来看看 Lua 5.1 对 这个#操作的定义,这个定义可以写的不是很好理解,但是也能看出来#对lua table的单目操作是定义在这个table里所有成员都是非nil的前提下,Lua 5.2的定义更容易让人明白,引用:

A program can modify the behavior of the length operator for any value
but strings through the __len metamethod (see §2.4).

Unless a __len metamethod is given, the length of a table t is only
defined if the table is a sequence, that is, the set of its positive
numeric keys is equal to {1..n} for some non-negative integer n. In
that case, n is its length. Note that a table like

 {10, 20, nil, 40} is not a sequence, because it has the key 4 but does not have the key 3. (So, there is no n such that the set {1..n}

is equal to the set of positive numeric keys of that table.) Note,
however, that non-numeric keys do not interfere with whether a table
is a sequence.

可以看到,类似{10, 20, nil, 40}这样的table并不能定义为一个sequence,自然#符号对这个table的操作就是无效的,未有定义的,如果一定要计算这样的table或者处理table中有a=2 这样的非sequence元素的时候,则需要自己修改metatable来定义__len这个函数实现自定义的处理方法,这个下次再说。

因为这个原因业务上吃了大亏,记录下修改代码去了


河马大侠
368 声望125 粉丝

引用和评论

0 条评论